package com.example.test.suppert.dao.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.test.suppert.BaseDo;
import com.example.test.suppert.dao.BaseService;
import com.example.test.suppert.dao.SnowflakeIdWorker;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.Serializable;
import java.util.*;

/**
 * Created by lsl on 2021/3/4.
 */
@Slf4j
public abstract class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseDo> extends ServiceImpl<M, T> implements BaseService<T> {
    @Autowired
    private M mapper;
    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;

    public BaseServiceImpl() {
    }

    @Override
    public Integer insert(T insertDo) {
        if (Objects.nonNull(insertDo) && Objects.isNull(insertDo.getId())) {
            insertDo.setId(snowflakeIdWorker.nextId());
        }
        return this.doInsert(insertDo);
    }

    private Integer doInsert(T insertDo) {
        Date now = new Date();
        insertDo.setCreateDate(now);
        insertDo.setUpdateDate(now);
        insertDo.setVersion(0);
        insertDo.setDeleted(0);
        return this.mapper.insert(insertDo);
    }

    @Override
    public Integer delete(T deleteDo) {
        deleteDo.setDeleted(1);
        return this.doUpdate(deleteDo);
    }

    private Integer doUpdate(T updateDo) {
        updateDo.setUpdateDate(new Date());
        return this.mapper.updateById(updateDo);
    }

    @Override
    public Integer deleteById(Serializable id) {
        return this.mapper.deleteById(id);
    }

    @Override
    public Integer update(T updateDo) {
        return this.doUpdate(updateDo);
    }

    @Override
    public Integer count(QueryWrapper<T> queryWrapper) {
        return this.mapper.selectCount(queryWrapper);
    }

    @Override
    public Integer count(T countDo) {
        return this.mapper.selectCount(new QueryWrapper<>(countDo));
    }

    @Override
    public T selectOne(T selectDo) {
        selectDo.setDeleted(0);
        return this.mapper.selectOne(new QueryWrapper<>(selectDo));
    }

    @Override
    public PageInfo<T> page(T pageDo) {
        this.setPage(pageDo.getPageBegin(), pageDo.getPageSize());
        List<T> list = this.mapper.selectList(new QueryWrapper<>(pageDo));
        return new PageInfo<>(list);
    }

    private void setPage(Integer pageBegin, Integer pageSize) {
        if (Objects.nonNull(pageBegin) && Objects.nonNull(pageSize)) {
            PageHelper.startPage(pageBegin, pageSize);
        } else {
            PageHelper.startPage(1, 10);
        }
    }

    @Override
    public PageInfo<Map<String, Long>> pageMap(T pageDo, QueryWrapper<T> queryWrapper) {
        this.setPage(pageDo.getPageBegin(), pageDo.getPageSize());
        List<Map<String, Object>> maps = this.mapper.selectMaps(queryWrapper);
        return new PageInfo(maps);
    }

    @Override
    public PageInfo<T> page(T pageDo, QueryWrapper<T> queryWrapper) {
        this.setPage(pageDo.getPageBegin(), pageDo.getPageSize());
        List<T> list = this.mapper.selectList(queryWrapper);
        return new PageInfo<>(list);
    }

    @Override
    public List<T> list(QueryWrapper<T> queryWrapper, Integer pageBegin, Integer pageSize) {
        if (Objects.isNull(pageBegin) || Objects.isNull(pageSize)) {
            pageBegin = 1;
            pageSize = 50;
        }
        this.setPage(pageBegin, pageSize);
        T queryDo = queryWrapper.getEntity();
        queryDo.setDeleted(0);
        List<T> list = this.mapper.selectList(new QueryWrapper<>(queryDo));
        return list == null ? Collections.emptyList() : list;
    }
}
